#ifndef BASESURFACE_H
#define BASESURFACE_H

#include <QImage>
#include <QObject>
#include <QOpenGLBuffer>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QOpenGLVertexArrayObject>
#include <QQuickItem>
#include <QTimerEvent>

#include "../videorecord/baserecorder.h"

#ifdef __aarch64__
#include "../videorecord/videorecorder_cv.h"
#include "../videorecord/videorecorder_mpp.h"
#endif

#include <memory>

#include "../camera/videocapturer.h"
#include "../videorecord/videorecorder_ffmpeg.h"

struct AVFrame;

enum class eImageType {
  YUV422,  // planed
  RGB888
};

// 渲染对象
class Render : public QObject, protected QOpenGLFunctions {
  Q_OBJECT

 public:
  Render();

  // 设置视窗大小
  void setViewportSize(const QSize& size);

  // 设置窗口指针
  void setWindow(QQuickWindow* win);

  // 设置最新的画面
  void setLastImg(std::shared_ptr<AVFrame> img, eImageType type);

  // 初始化
  bool init();

 public slots:
  // 绘制
  void paint();

  // 记录视频
  void record();

 protected:
  //
  void timerEvent(QTimerEvent* event) override;

 private:
  // 更新纹理数据
  void updateTex();

 signals:
  void captured(std::shared_ptr<QImage> img);

 private:
  // 窗口大小
  QSize m_windowSize;
  QQuickWindow* m_pWindow{nullptr};

  // 最新要显示的帧
  std::shared_ptr<AVFrame> m_spLastFrame;

  // 图像的类型，yuv或者rgb
  eImageType m_imgType;

  // opengl
  QOpenGLShaderProgram* m_pProgram{nullptr};
  QOpenGLBuffer m_vbo;
  QOpenGLVertexArrayObject m_vao;

  // RGB 纹理
  QOpenGLTexture m_texRgb;

  // YUV纹理
  QOpenGLTexture m_texY;
  QOpenGLTexture m_texU;
  QOpenGLTexture m_texV;

  // 蒙版
  QOpenGLTexture m_texMask;

  // 帧数统计
  int m_iFrameCount{0};
  int m_iFrameCountTimer{0};
};

class BaseSurface : public QQuickItem {
  Q_OBJECT
  Q_PROPERTY(VideoCapturer* source WRITE setSource)

 public:
  BaseSurface();

 public slots:
  // 处理窗口变化
  void handleWindowChanged(QQuickWindow* win);

  // 同步
  void sync();

  // 接受待显示的图像
  void updateSurface(std::shared_ptr<AVFrame> img);

  // 设置源，
  void setSource(VideoCapturer* src);

 signals:

 private:
  // 渲染器
  Render* m_pRender{nullptr};

  // 最新画面
  std::shared_ptr<AVFrame> m_spLastFrame;
  eImageType m_imgType;

  // 编码录像
  BaseRecorder* m_pRecoder{nullptr};
};

#endif  // BASESURFACE_H
